ImageSave.py

Save Image(s) from Camera(s)

It shows how to save one or more images from cameras in RAW, JPEG, BMP, TIFF, and PNG format.

1 # -- coding: utf-8 --
2 
3 import sys
4 import os
5 import platform
6 from ctypes import *
7 
8 # Compatible with different operating systems to load DDL
9 currentsystem = platform.system()
10 if currentsystem == 'Windows':
11  sys.path.append(os.path.join(os.getenv('MVCAM_COMMON_RUNENV'), "Samples", "Python", "MvImport"))
12 else:
13  sys.path.append(os.path.join("..", "..", "MvImport"))
14 from MvCameraControl_class import *
15 
16 # Compatible with input processing of Python 2.X and 3.X
17 if sys.version_info[0] < 3:
18  # Python 2.x
19  input_func = raw_input
20 else:
21  # Python 3.x
22  input_func = input
23 
24 # Decoding Characters
25 def decoding_char(ctypes_char_array):
26  """
27  Safely decode a string from a ctypes character array.
28  Compatible with Python 2.x and 3.x, as well as 32-bit and 64-bit environments.
29  """
30  byte_str = memoryview(ctypes_char_array).tobytes()
31 
32  # Truncate at the first null character
33  null_index = byte_str.find(b'\x00')
34  if null_index != -1:
35  byte_str = byte_str[:null_index]
36 
37  # Attempt to decode using multiple encodings
38  for encoding in ['gbk', 'utf-8', 'latin-1']:
39  try:
40  return byte_str.decode(encoding)
41  except UnicodeDecodeError:
42  continue
43 
44  # If all encodings fail, use a replacement strategy
45  return byte_str.decode('latin-1', errors='replace')
46 
47 
48 HB_format_list = [
49  PixelType_Gvsp_HB_Mono8,
50  PixelType_Gvsp_HB_Mono10,
51  PixelType_Gvsp_HB_Mono10_Packed,
52  PixelType_Gvsp_HB_Mono12,
53  PixelType_Gvsp_HB_Mono12_Packed,
54  PixelType_Gvsp_HB_Mono16,
55  PixelType_Gvsp_HB_BayerGR8,
56  PixelType_Gvsp_HB_BayerRG8,
57  PixelType_Gvsp_HB_BayerGB8,
58  PixelType_Gvsp_HB_BayerBG8,
59  PixelType_Gvsp_HB_BayerRBGG8,
60  PixelType_Gvsp_HB_BayerGR10,
61  PixelType_Gvsp_HB_BayerRG10,
62  PixelType_Gvsp_HB_BayerGB10,
63  PixelType_Gvsp_HB_BayerBG10,
64  PixelType_Gvsp_HB_BayerGR12,
65  PixelType_Gvsp_HB_BayerRG12,
66  PixelType_Gvsp_HB_BayerGB12,
67  PixelType_Gvsp_HB_BayerBG12,
68  PixelType_Gvsp_HB_BayerGR10_Packed,
69  PixelType_Gvsp_HB_BayerRG10_Packed,
70  PixelType_Gvsp_HB_BayerGB10_Packed,
71  PixelType_Gvsp_HB_BayerBG10_Packed,
72  PixelType_Gvsp_HB_BayerGR12_Packed,
73  PixelType_Gvsp_HB_BayerRG12_Packed,
74  PixelType_Gvsp_HB_BayerGB12_Packed,
75  PixelType_Gvsp_HB_BayerBG12_Packed,
76  PixelType_Gvsp_HB_YUV422_Packed,
77  PixelType_Gvsp_HB_YUV422_YUYV_Packed,
78  PixelType_Gvsp_HB_RGB8_Packed,
79  PixelType_Gvsp_HB_BGR8_Packed,
80  PixelType_Gvsp_HB_RGBA8_Packed,
81  PixelType_Gvsp_HB_BGRA8_Packed,
82  PixelType_Gvsp_HB_RGB16_Packed,
83  PixelType_Gvsp_HB_BGR16_Packed,
84  PixelType_Gvsp_HB_RGBA16_Packed,
85  PixelType_Gvsp_HB_BGRA16_Packed]
86 
87 def save_non_raw_image(save_type, frame_info, cam_instance):
88 
89 
90  if save_type == 1:
91  mv_image_type = MV_Image_Jpeg
92  file_path = "Image_w%d_h%d_fn%d.jpg" % (
93  frame_info.stFrameInfo.nWidth, frame_info.stFrameInfo.nHeight, frame_info.stFrameInfo.nFrameNum)
94  elif save_type == 2:
95  mv_image_type = MV_Image_Bmp
96  file_path = "Image_w%d_h%d_fn%d.bmp" % (
97  frame_info.stFrameInfo.nWidth, frame_info.stFrameInfo.nHeight, frame_info.stFrameInfo.nFrameNum)
98  elif save_type == 3:
99  mv_image_type = MV_Image_Tif
100  file_path = "Image_w%d_h%d_fn%d.tif" % (
101  frame_info.stFrameInfo.nWidth, frame_info.stFrameInfo.nHeight, frame_info.stFrameInfo.nFrameNum)
102  else:
103  file_path = "Image_w%d_h%d_fn%d.png" % (
104  frame_info.stFrameInfo.nWidth, frame_info.stFrameInfo.nHeight, frame_info.stFrameInfo.nFrameNum)
105  mv_image_type = MV_Image_Png
106 
107  stImage = MV_CC_IMAGE()
108  memset(byref(stImage), 0, sizeof(MV_CC_IMAGE))
109  stImage.nWidth = frame_info.stFrameInfo.nExtendWidth # The image width
110  stImage.nHeight = frame_info.stFrameInfo.nExtendHeight # The image height
111  stImage.enPixelType = frame_info.stFrameInfo.enPixelType # The image pixel format
112  stImage.pImageBuf = frame_info.pBufAddr
113  stImage.nImageBufSize = frame_info.stFrameInfo.nFrameLenEx
114  stImage.nImageLen = frame_info.stFrameInfo.nFrameLenEx
115 
116  stSaveImageParam = MV_CC_SAVE_IMAGE_PARAM()
117  memset(byref(stSaveImageParam), 0, sizeof(MV_CC_SAVE_IMAGE_PARAM))
118  stSaveImageParam.enImageType = mv_image_type # The image format for saving
119  stSaveImageParam.iMethodValue = 1
120  stSaveImageParam.nQuality = 80 # JPG: (50,99], invalid in other format
121  stSaveImageParam.nEndian = 0 # Endianness for saving TIFF images (little-endian mode by default)
122 
123  mv_ret = cam_instance.MV_CC_SaveImageToFileEx2(stImage, stSaveImageParam, file_path)
124  return mv_ret
125 
126 
127 def save_raw(frame_info, cam_instance):
128  if frame_info.stFrameInfo.enPixelType in HB_format_list:
129 
130  # Decode parameters
131  stDecodeParam = MV_CC_HB_DECODE_PARAM()
132  memset(byref(stDecodeParam), 0, sizeof(stDecodeParam))
133 
134  # Gets the size of the device payload.
135  nDevPayloadSize = c_uint64()
136  nMemAlignment = c_uint()
137  ret = cam_instance.MV_CC_GetPayloadSize(nDevPayloadSize, nMemAlignment)
138  if 0 != ret:
139  print("Get PayloadSize fail! ret[0x%x]" % ret)
140  return ret
141  nPayloadSize = nDevPayloadSize.value
142  stDecodeParam.pSrcBuf = frame_info.pBufAddr
143  stDecodeParam.nSrcLen = frame_info.stFrameInfo.nFrameLen
144  stDecodeParam.pDstBuf = (c_ubyte * nPayloadSize)()
145  stDecodeParam.nDstBufSize = nPayloadSize
146  ret = cam_instance.MV_CC_HBDecode(stDecodeParam)
147  if ret != 0:
148  print("HB Decode fail! ret[0x%x]" % ret)
149  return ret
150  else:
151  file_path = "Image_w%d_h%d_fn%d.raw" % (stDecodeParam.nWidth, stDecodeParam.nHeight,
152  frame_info.stFrameInfo.nFrameNum)
153  try:
154  file_open = open(file_path.encode('ascii'), 'wb+')
155  img_save = (c_ubyte * stDecodeParam.nDstBufLen)()
156  memmove(byref(img_save), stDecodeParam.pDstBuf, stDecodeParam.nDstBufLen)
157  file_open.write(img_save)
158  except PermissionError:
159  file_open.close()
160  print("save error raw file executed failed!")
161  return MV_E_OPENFILE
162  file_open.close()
163  else:
164  file_path = "Image_w%d_h%d_fn%d.raw" % (
165  frame_info.stFrameInfo.nWidth, frame_info.stFrameInfo.nHeight, frame_info.stFrameInfo.nFrameNum)
166  try:
167  file_open = open(file_path.encode('ascii'), 'wb+')
168  img_save = (c_ubyte * frame_info.stFrameInfo.nFrameLen)()
169  memmove(byref(img_save), frame_info.pBufAddr, frame_info.stFrameInfo.nFrameLen)
170  file_open.write(img_save)
171  except PermissionError:
172  file_open.close()
173  print("save error raw file executed failed!")
174  return MV_E_OPENFILE
175  file_open.close()
176  return 0
177 
178 
179 if __name__ == "__main__":
180 
181  try:
182  # Initialize SDK resources
183  MvCamera.MV_CC_Initialize()
184 
185  SDKVersion = MvCamera.MV_CC_GetSDKVersion()
186  print ("SDKVersion[0x%x]" % SDKVersion)
187 
188  deviceList = MV_CC_DEVICE_INFO_LIST()
189  tlayerType = (MV_GIGE_DEVICE | MV_USB_DEVICE | MV_GENTL_CAMERALINK_DEVICE
190  | MV_GENTL_CXP_DEVICE | MV_GENTL_XOF_DEVICE)
191 
192  # Enumerate devices
193  ret = MvCamera.MV_CC_EnumDevices(tlayerType, deviceList)
194  if ret != 0:
195  print("enum devices fail! ret[0x%x]" % ret)
196  sys.exit()
197 
198  if deviceList.nDeviceNum == 0:
199  print("find no device!")
200  sys.exit()
201 
202  print("Find %d devices!" % deviceList.nDeviceNum)
203 
204  for i in range(0, deviceList.nDeviceNum):
205  mvcc_dev_info = cast(deviceList.pDeviceInfo[i], POINTER(MV_CC_DEVICE_INFO)).contents
206  if mvcc_dev_info.nTLayerType == MV_GIGE_DEVICE or mvcc_dev_info.nTLayerType == MV_GENTL_GIGE_DEVICE:
207  print("\ngige device: [%d]" % i)
208  strModeName = decoding_char(mvcc_dev_info.SpecialInfo.stGigEInfo.chModelName)
209  print("device model name: %s" % strModeName)
210  strSerialNumber = decoding_char(mvcc_dev_info.SpecialInfo.stGigEInfo.chSerialNumber)
211  print("device serial number: %s" % strSerialNumber)
212  nip1 = ((mvcc_dev_info.SpecialInfo.stGigEInfo.nCurrentIp & 0xff000000) >> 24)
213  nip2 = ((mvcc_dev_info.SpecialInfo.stGigEInfo.nCurrentIp & 0x00ff0000) >> 16)
214  nip3 = ((mvcc_dev_info.SpecialInfo.stGigEInfo.nCurrentIp & 0x0000ff00) >> 8)
215  nip4 = (mvcc_dev_info.SpecialInfo.stGigEInfo.nCurrentIp & 0x000000ff)
216  print("current ip: %d.%d.%d.%d\n" % (nip1, nip2, nip3, nip4))
217  elif mvcc_dev_info.nTLayerType == MV_USB_DEVICE:
218  print("\nu3v device: [%d]" % i)
219  strModeName = decoding_char(mvcc_dev_info.SpecialInfo.stUsb3VInfo.chModelName)
220  print ("device model name: %s" % strModeName)
221 
222  strSerialNumber = decoding_char(mvcc_dev_info.SpecialInfo.stUsb3VInfo.chSerialNumber)
223  print ("device serial number: %s" % strSerialNumber)
224  elif mvcc_dev_info.nTLayerType == MV_GENTL_CAMERALINK_DEVICE:
225  print ("\nCML device: [%d]" % i)
226  strModeName = decoding_char(mvcc_dev_info.SpecialInfo.stCMLInfo.chModelName)
227  print ("device model name: %s" % strModeName)
228 
229  strSerialNumber = decoding_char(mvcc_dev_info.SpecialInfo.stCMLInfo.chSerialNumber)
230  print ("device serial number: %s" % strSerialNumber)
231  elif mvcc_dev_info.nTLayerType == MV_GENTL_CXP_DEVICE:
232  print ("\nCXP device: [%d]" % i)
233  strModeName = decoding_char(mvcc_dev_info.SpecialInfo.stCXPInfo.chModelName)
234  print ("device model name: %s" % strModeName)
235 
236  strSerialNumber = decoding_char(mvcc_dev_info.SpecialInfo.stCXPInfo.chSerialNumber)
237  print ("device serial number: %s" % strSerialNumber)
238  elif mvcc_dev_info.nTLayerType == MV_GENTL_XOF_DEVICE:
239  print ("\nXoF device: [%d]" % i)
240  strModeName = decoding_char(mvcc_dev_info.SpecialInfo.stXoFInfo.chModelName)
241  print ("device model name: %s" % strModeName)
242 
243  strSerialNumber = decoding_char(mvcc_dev_info.SpecialInfo.stXoFInfo.chSerialNumber)
244  print ("device serial number: %s" % strSerialNumber)
245 
246  nConnectionNum = input_func("please input the number of the device to connect:")
247 
248  if int(nConnectionNum) >= deviceList.nDeviceNum:
249  print("input error!")
250  sys.exit()
251 
252  nSaveImageType = input_func("please input number (0-raw, 1-Jpeg, 2-Bmp, 3-Tiff, 4-Png):")
253  if int(nSaveImageType) not in {0, 1, 2, 3, 4}:
254  print("input error!")
255  sys.exit()
256 
257  # Create a camera instance
258  cam = MvCamera()
259 
260  # Select a device, and create a handle
261  stDeviceList = cast(deviceList.pDeviceInfo[int(nConnectionNum)], POINTER(MV_CC_DEVICE_INFO)).contents
262 
263  ret = cam.MV_CC_CreateHandle(stDeviceList)
264  if ret != 0:
265  raise Exception("create handle fail! ret[0x%x]" % ret)
266 
267  # Turn on the device
268  ret = cam.MV_CC_OpenDevice(MV_ACCESS_Exclusive, 0)
269  if ret != 0:
270  raise Exception("open device fail! ret[0x%x]" % ret)
271 
272  # Get optimal packet size (only supported by GigE devices)
273  if stDeviceList.nTLayerType == MV_GIGE_DEVICE or stDeviceList.nTLayerType == MV_GENTL_GIGE_DEVICE:
274  nPacketSize = cam.MV_CC_GetOptimalPacketSize()
275  if int(nPacketSize) > 0:
276  ret = cam.MV_CC_SetIntValue("GevSCPSPacketSize", nPacketSize)
277  if ret != 0:
278  print("Warning: Set Packet Size fail! ret[0x%x]" % ret)
279  else:
280  print("Warning: Get Packet Size fail! ret[0x%x]" % nPacketSize)
281 
282  # Set trigger mode to off
283  ret = cam.MV_CC_SetEnumValue("TriggerMode", MV_TRIGGER_MODE_OFF)
284  if ret != 0:
285  raise Exception("set trigger mode fail! ret[0x%x]" % ret)
286 
287  # Start grabbing images
288  ret = cam.MV_CC_StartGrabbing()
289  if ret != 0:
290  raise Exception("start grabbing fail! ret[0x%x]" % ret)
291 
292  # Obtained frame information
293  stOutFrame = MV_FRAME_OUT()
294  memset(byref(stOutFrame), 0, sizeof(stOutFrame))
295 
296  ret = cam.MV_CC_GetImageBuffer(stOutFrame, 20000)
297  if None != stOutFrame.pBufAddr and 0 == ret:
298  print("get one frame: Width[%d], Height[%d], nFrameNum[%d]" % (
299  stOutFrame.stFrameInfo.nWidth, stOutFrame.stFrameInfo.nHeight, stOutFrame.stFrameInfo.nFrameNum))
300 
301  # If the image is in HB format, it should be decoded first before being saved to RAW format
302  if int(nSaveImageType) == 0:
303  ret = save_raw(stOutFrame, cam)
304  else:
305  ret = save_non_raw_image(int(nSaveImageType), stOutFrame, cam)
306  if ret != 0:
307  cam.MV_CC_FreeImageBuffer(stOutFrame)
308  raise Exception("save image fail! ret[0x%x]" % ret)
309  else:
310  print("Save image success!")
311 
312  cam.MV_CC_FreeImageBuffer(stOutFrame)
313  else:
314  raise Exception("no data[0x%x]" % ret)
315 
316  # Stop grabbing images
317  ret = cam.MV_CC_StopGrabbing()
318  if ret != 0:
319  raise Exception("stop grabbing fail! ret[0x%x]" % ret)
320 
321  # Turn off the device
322  ret = cam.MV_CC_CloseDevice()
323  if ret != 0:
324  raise Exception("close device fail! ret[0x%x]" % ret)
325 
326  # Destroy the handle
327  cam.MV_CC_DestroyHandle()
328 
329  except Exception as e:
330  print(e)
331  cam.MV_CC_CloseDevice()
332  cam.MV_CC_DestroyHandle()
333  finally:
334  # Release SDK resources
335  MvCamera.MV_CC_Finalize()